package com.example.demo.service.Impl;

import com.example.demo.aop.Logger;
import com.example.demo.entity.*;
import com.example.demo.handler.StockNewsHandler;
import com.example.demo.mapper.*;
import com.example.demo.service.IMessageService;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.reflect.TypeToken;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
public class MessageServiceImpl implements IMessageService{

    private static final String ChineseIndexAddress = "https://push2.eastmoney.com/api/qt/clist/get?np=1&fltt=1&invt=2&cb=jQuery371024930268392261878_1747332334755&fs=i%3A1.000001%2Ci%3A0.399001%2Ci%3A0.399005%2Ci%3A0.399006%2Ci%3A1.000300%2Ci%3A100.HSI%2Ci%3A100.HSCEI%2Ci%3A124.HSCCI%2Ci%3A100.TWII%2Ci%3A100.N225%2Ci%3A100.KOSPI200%2Ci%3A100.KS11%2Ci%3A100.STI%2Ci%3A100.SENSEX%2Ci%3A100.KLSE%2Ci%3A100.SET%2Ci%3A100.PSI%2Ci%3A100.KSE100%2Ci%3A100.VNINDEX%2Ci%3A100.JKSE%2Ci%3A100.CSEALL&fields=f12%2Cf13%2Cf14%2Cf292%2Cf1%2Cf2%2Cf4%2Cf3%2Cf152&fid=&pn=1&pz=100&po=1&ut=fa5fd1943c7b386f172d6893dbfba10b&dect=1&wbp2u=%7C0%7C0%7C0%7Cweb&_=1747332334768";
    private static final String ListingCalendarAddress = "https://vip.stock.finance.sina.com.cn/corp/go.php/vRPD_NewStockIssue/page/1.phtml";
    private static final String SecuritiesNewsAddress = "https://np-weblist.eastmoney.com/comm/web/getFastNewsList?client=web&biz=web_724&fastColumn=102&sortEnd=&pageSize=50&req_trace=1747451642107&_=1747451642109&callback=jQuery183030005853316022946_1747451642050";
    private static final String HsgFundFlowAddress = "https://push2.eastmoney.com/api/qt/kamt/get?fields1=f1,f2,f3,f4&fields2=f51,f52,f53,f54,f56,f60,f61,f62,f63,f65,f66&ut=fa5fd1943c7b386f172d6893dbfba10b&cb=jQuery112303826434369432341_1747454717297&_=1747454717298";
    private static final String SectorFundFlowDailyChangeAddress = "https://push2.eastmoney.com/api/qt/clist/get?cb=jQuery112308277452156198984_1747458988020&fid=f62&po=1&pz=86&pn=1&np=1&fltt=2&invt=2&ut=8dec03ba335b81bf4ebdf7b29ec27d15&fs=m%3A90+t%3A2&fields=f12%2Cf14%2Cf2%2Cf3%2Cf62%2Cf184%2Cf66%2Cf69%2Cf72%2Cf75%2Cf78%2Cf81%2Cf84%2Cf87%2Cf204%2Cf205%2Cf124%2Cf1%2Cf13";

    @Autowired
    private ChineseIndexMapper chineseIndexMapper;

    @Autowired
    private ListingCalendarMapper listingCalendarMapper;

    @Autowired
    private SecuritiesNewsMapper securitiesNewsMapper;

    @Autowired
    private HsgtFundFlowMapper hsgFundFlowMapper;

    @Autowired
    private SectorFundFlowDailyChangeMapper sectorFundFlowDailyChangeMapper;

    @Autowired
    private StockNewsHandler stockNewsHandler;

    @Logger(description = "爬取中国指数", url = ChineseIndexAddress, dataSheer = "chinese_index")
    @Override
    public void getChineseIndex() {
        try {
            URL url = new URL(ChineseIndexAddress);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("User-Agent", "Mozilla/5.0");

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            conn.disconnect();

            // 2. 剥离JSONP包装
            String jsonpResponse = response.toString();
            int startIndex = jsonpResponse.indexOf("(") + 1;
            int endIndex = jsonpResponse.lastIndexOf(")");
            String jsonString = jsonpResponse.substring(startIndex, endIndex);

            // 3. 使用Gson解析JSON
            Gson gson = new Gson();
            JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class); // 先解析为 JsonObject
            JsonObject dataObject = jsonObject.getAsJsonObject("data"); // 提取 "data" 对象
            List<ChineseIndex> indexList = gson.fromJson(
                    dataObject.getAsJsonArray("diff"), // 提取 "diff" 数组
                    new TypeToken<List<ChineseIndex>>() {}.getType()
            );

            // 4. 处理解析后的数据
            for (ChineseIndex index: indexList){
                if(!chineseIndexMapper.selectById(index.getId())){
                    chineseIndexMapper.insertChineseIndex(index);
                }else {
                    chineseIndexMapper.updateChineseIndex(index);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Logger(description = "爬取新股上市日历", url = ListingCalendarAddress, dataSheer = "listing_calendar")
    @Override
    public void getListingCalendar() {

        List<ListingCalendar> list = new ArrayList<>();

        // 定义日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");


        try {
            Document doc = Jsoup.connect(ListingCalendarAddress).get();

            Element table = doc.getElementById("NewStockTable");

            Elements tbody = table.select("tbody > tr");
            for (int i = 3; i <= tbody.size(); i++){

                Elements tr = tbody.get(i-1).select("td");
                // 选择第一个td
                Element firstTd = tr.select("td").get(0);
                String firstTdData = firstTd.select("div").text();
                // 选择第三个td
                Element thirdTd = tr.select("td").get(2);
                String thirdTdData = thirdTd.select("a").text();
                // 选择第四个td
                Element fourthTd = tr.select("td").get(3);
                String fourthTdData = fourthTd.select("div").text();

                ListingCalendar listingCalendar = new ListingCalendar();

                listingCalendar.setId(firstTdData);
                listingCalendar.setName(thirdTdData);
                // 解析字符串为Date对象
                Date date = sdf.parse(fourthTdData);
                listingCalendar.setListingDate(date);

                list.add(listingCalendar);
            }

            for (ListingCalendar index: list){
                if(!listingCalendarMapper.selectById(index.getId())){
                    listingCalendarMapper.insertListingCalendar(index);
                }else {
                    listingCalendarMapper.updateListingCalendar(index);
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }

    }

    @Logger(description = "爬取证券快讯", url = SecuritiesNewsAddress, dataSheer = "securities_news")
    @Override
    public void getSecuritiesNews() {
        try {
            URL url = new URL(SecuritiesNewsAddress);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("User-Agent", "Mozilla/5.0");

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            conn.disconnect();

            // 2. 剥离JSONP包装
            String jsonpResponse = response.toString();
            int startIndex = jsonpResponse.indexOf("(") + 1;
            int endIndex = jsonpResponse.lastIndexOf(")");
            String jsonString = jsonpResponse.substring(startIndex, endIndex);

            // 3. 使用Gson解析JSON
            Gson gson = new Gson();
            JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class); // 先解析为 JsonObject
            JsonObject dataObject = jsonObject.getAsJsonObject("data"); // 提取 "data" 对象
            List<SecuritiesNews> indexList = gson.fromJson(
                    dataObject.getAsJsonArray("fastNewsList"), // 提取 "fastNewsList" 数组
                    new TypeToken<List<SecuritiesNews>>() {}.getType()
            );

            // 4. 处理解析后的数据
            for (SecuritiesNews index: indexList){
                index.setTitle(extractTitle(index.getTitle()));
                if(!securitiesNewsMapper.selectById(index.getId())){
                    securitiesNewsMapper.insertSecuritiesNews(index);

                    stockNewsHandler.pushIncrementalData(index);
                }else {
                    securitiesNewsMapper.updateSecuritiesNews(index);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    @Logger(description = "爬取港股通资金流", url = HsgFundFlowAddress, dataSheer = "hsg_fund_flow")
    @Override
    public void getHsgFundFlow() {
        try {
            URL url = new URL(HsgFundFlowAddress);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("User-Agent", "Mozilla/5.0");

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            conn.disconnect();

            // 2. 剥离JSONP包装
            String jsonpResponse = response.toString();
            int startIndex = jsonpResponse.indexOf("(") + 1;
            int endIndex = jsonpResponse.lastIndexOf(")");
            String jsonString = jsonpResponse.substring(startIndex, endIndex);

            // 3. 使用Gson解析JSON
            Gson gson = new Gson();
            JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class); // 先解析为 JsonObject
            JsonObject dataObject = jsonObject.getAsJsonObject("data"); // 提取 "data" 对象

            // 提取sh2hk数据
            JsonObject sh2hkObject = dataObject.getAsJsonObject("sh2hk");
            HsgtFundFlow hsgtFundFlow1 = gson.fromJson(sh2hkObject,HsgtFundFlow.class);
            hsgtFundFlow1.setId("sh2hk");
            hsgtFundFlow1.setStatus(1l);
            hsgtFundFlow1.setNetBuyAmount(formatAmount(hsgtFundFlow1.getNetBuyAmount()));
            hsgtFundFlow1.setTotalTradingVolume(formatAmount(hsgtFundFlow1.getTotalTradingVolume()));
            if(!hsgFundFlowMapper.selectById(hsgtFundFlow1.getId())){
                hsgFundFlowMapper.insertHsgtFundFlow(hsgtFundFlow1);
            }else {
                hsgFundFlowMapper.updateHsgtFundFlow(hsgtFundFlow1);
            }

            // 提取sz2hk数据
            JsonObject sz2hkObject = dataObject.getAsJsonObject("sz2hk");
            HsgtFundFlow hsgtFundFlow2 = gson.fromJson(sz2hkObject,HsgtFundFlow.class);
            hsgtFundFlow2.setId("sz2hk");
            hsgtFundFlow2.setStatus(2l);
            hsgtFundFlow2.setNetBuyAmount(formatAmount(hsgtFundFlow2.getNetBuyAmount()));
            hsgtFundFlow2.setTotalTradingVolume(formatAmount(hsgtFundFlow2.getTotalTradingVolume()));
            if(!hsgFundFlowMapper.selectById(hsgtFundFlow2.getId())){
                hsgFundFlowMapper.insertHsgtFundFlow(hsgtFundFlow2);
            }else {
                hsgFundFlowMapper.updateHsgtFundFlow(hsgtFundFlow2);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Logger(description = "爬取板块资金流今日跌涨幅", url = SectorFundFlowDailyChangeAddress, dataSheer = "sector_fund_flow_daily_change")
    @Override
    public void getSectorFundFlowDailyChange() {
        try {
            URL url = new URL(SectorFundFlowDailyChangeAddress);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setRequestProperty("User-Agent", "Mozilla/5.0");

            BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            conn.disconnect();

            // 2. 剥离JSONP包装
            String jsonpResponse = response.toString();
            int startIndex = jsonpResponse.indexOf("(") + 1;
            int endIndex = jsonpResponse.lastIndexOf(")");
            String jsonString = jsonpResponse.substring(startIndex, endIndex);
            System.out.println(jsonString);

            // 3. 使用Gson解析JSON
            Gson gson = new Gson();
            JsonObject jsonObject = gson.fromJson(jsonString, JsonObject.class); // 先解析为 JsonObject
            JsonObject dataObject = jsonObject.getAsJsonObject("data"); // 提取 "data" 对象
            List<SectorFundFlowDailyChange> indexList = gson.fromJson(
                    dataObject.getAsJsonArray("diff"), // 提取 "fastNewsList" 数组
                    new TypeToken<List<SectorFundFlowDailyChange>>() {}.getType()
            );

            // 4. 处理解析后的数据
            for (SectorFundFlowDailyChange index: indexList){
                if(!sectorFundFlowDailyChangeMapper.selectById(index.getId())){
                    sectorFundFlowDailyChangeMapper.insertSectorFundFlowDailyChange(index);
                }else {
                    sectorFundFlowDailyChangeMapper.updateSectorFundFlowDailyChange(index);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static String extractTitle(String newsText) {
        int startBracket = newsText.indexOf("【");
        int endBracket = newsText.indexOf("】");

        // 存在合法中括号时，保留括号并提取内容
        if (startBracket != -1 && endBracket != -1 && startBracket < endBracket) {
            return newsText.substring(startBracket, endBracket + 1); // 包含【】
        } else {
            // 无中括号时，按逗号截取并保留原文本（不截断符号）
            int commaIndex = newsText.indexOf("，"); // 使用中文逗号
            if (commaIndex != -1) {
                return newsText.substring(0, commaIndex + 1); // 保留逗号
            } else {
                return newsText; // 无逗号则返回全文
            }
        }
    }

    /**
     * 金额除以10000并保留两位小数
     */
    private static String formatAmount(String amount) {
        return BigDecimal.valueOf(Double.valueOf(amount))
                .divide(BigDecimal.valueOf(10000), 2, RoundingMode.HALF_UP)
                .toString();
    }

}
